<script setup>
import api from '@/api'
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { formatBytes, formatSeconds } from '@/utils'
import { useRoute, useRouter } from 'vue-router'
import { showToast, showDialog } from 'vant'

const route = useRoute()
const router = useRouter()

const pageLoading = ref(true)
const state = ref('ready')
const time = ref(0)
const size = ref(0)
const percent = ref('')
const material = ref(null)
const color = ref(localStorage.getItem('CLIP_COLOR') || '#FFFFFF')
const popupColorVisible = ref(false)
const colors = ref(['#FFFFFF', '#F53F3F', '#F77234', '#F7BA1E', '#FADC19', '#9FDB1D', '#00B42A', '#14C9C9', '#3491FA', '#165DFF', '#722ED1', '#D91AD9'])
const recordRef = ref()

let stream
let mediaRecorder
let startTime
let recordSize = 0
let recordedChunks = []

onMounted(() => {
  Promise.all([getMaterial(), init()]).finally(() => {
    pageLoading.value = false
  })
})

onBeforeUnmount(() => {
  recordedChunks = []
  if (stream) {
    stream.getTracks().forEach(function (track) {
      track.stop()
    })
  }
  recordRef.value.srcObject = null
})

const getMaterial = async () => {
  try {
    material.value = await api.get(`ip/materials/` + route.params.id)
  } catch (error) {
    console.error(error)
  }
}

const init = async () => {
  nextTick(async () => {
    stream = await navigator.mediaDevices.getUserMedia({
      video: {
        // width:720,
        // height:1280,
        facingMode: 'user',
      },
      audio: true,
    })

    recordRef.value.srcObject = stream

    mediaRecorder = new MediaRecorder(stream)

    mediaRecorder.onstart = () => {
      recordedChunks = []
      recordSize = 0
      startTime = new Date().getTime()
    }

    mediaRecorder.ondataavailable = (event) => {
      recordSize += event.data.size
      time.value = Math.round((new Date().getTime() - startTime) / 1000)
      size.value = recordSize
      if (event.data.size > 0) {
        recordedChunks.push(event.data)
      }
    }

    mediaRecorder.onstop = async () => {
      if (stream) {
        stream.getTracks().forEach(function (track) {
          track.stop()
        })
      }

      recordRef.srcObject = null

      let resp = await api.post('ip/materials/getOssUploadUrl')

      const formData = new FormData()
      formData.append('key', resp.filename)
      formData.append('OSSAccessKeyId', resp.accessid)
      formData.append('policy', resp.policy)
      formData.append('signature', resp.signature)
      formData.append('file', new File(recordedChunks, 'file.webm', { type: mediaRecorder.mimeType }))
      const video_url = resp.host + '/' + resp.mp4

      percent.value = '0%'
      const uploadRequestXHR = new XMLHttpRequest()
      uploadRequestXHR.open('POST', resp.host, true)

      uploadRequestXHR.onerror = () => {
        showToast('上传失败')
      }
      uploadRequestXHR.upload.onprogress = (e) => {
        let per = Math.floor((e.loaded / e.total) * 100)

        // 控制进度条最大显示99%，最后请求结束后才变为100%
        if (per > 99) {
          per = 99
        }

        percent.value = per + '%'
      }
      uploadRequestXHR.onload = () => {
        if (uploadRequestXHR.status != 204) {
          showToast('上传失败')
          return
        }

        api
          .post('ip/videos', {
            material_id: material.value.id,
            url: video_url,
            size: size.value,
            times: time.value,
          })
          .then(() => {
            percent.value = '100%'

            showDialog({ message: '录制已完成' }).then(() => {
              router.push('/ip/videos')
            })
          })
      }

      uploadRequestXHR.send(formData)
    }
  })
}

const selectColor = (item) => {
  color.value = item
  localStorage.setItem('CLIP_COLOR', item)
}

const changeState = () => {
  if (state.value == 'ready') {
    state.value = 'recording'
    // 开始录制
    mediaRecorder.start(1000)
  } else if (state.value == 'recording') {
    state.value = 'uploading'
    // 结束录制
    mediaRecorder.stop()
  }
}
</script>

<template>
  <div class="page">
    <van-overlay :show="pageLoading" z-index="1000">
      <van-loading size="24px" color="#fff" class="transform-center"></van-loading>
    </van-overlay>

    <van-nav-bar class="navbar" :title="material ? material.title : ''" left-arrow @click-left="$router.go(-1)">
      <template #right>
        <svg @click="popupColorVisible = true" style="width: 20px" t="1721953991133" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2365" width="200" height="200">
          <path
            d="M163.797333 249.941333c125.44-167.082667 385.28-215.68 570.197334-100.693333 182.613333 113.493333 249.770667 331.776 174.933333 536.618667-70.613333 193.365333-256.682667 269.994667-390.784 172.714666-50.218667-36.437333-69.717333-82.133333-79.104-156.330666l-4.522667-42.154667-1.92-16.938667c-5.248-39.850667-13.269333-57.728-30.08-67.072-22.826667-12.714667-38.058667-13.013333-68.053333-1.408l-14.976 6.229334-7.637333 3.328c-43.264 18.773333-72.021333 25.386667-108.416 17.749333l-8.533334-2.005333-6.997333-2.005334c-118.997333-36.864-136.618667-198.272-24.106667-348.032z m41.984 286.549334l5.248 1.536 5.717334 1.322666c18.730667 3.712 34.730667 0.64 61.312-10.325333l25.685333-10.965333c51.285333-21.034667 84.693333-23.082667 129.962667 2.133333 39.125333 21.802667 54.4 55.381333 62.165333 113.493333l2.261333 19.584 2.346667 22.656 2.005333 18.048c7.338667 58.069333 20.693333 89.173333 53.248 112.810667 97.066667 70.4 236.117333 13.141333 293.12-142.890667 64.682667-177.152 7.424-363.264-148.650666-460.330666-156.8-97.450667-379.690667-55.765333-485.248 84.778666-88.533333 117.888-77.653333 225.28-9.173334 248.149334z m478.933334-85.077334a53.333333 53.333333 0 1 1 102.997333-27.648 53.333333 53.333333 0 0 1-102.997333 27.648z m21.077333 148.821334a53.333333 53.333333 0 1 1 103.04-27.605334 53.333333 53.333333 0 0 1-103.04 27.605334zM600.32 323.285333a53.333333 53.333333 0 1 1 103.04-27.605333 53.333333 53.333333 0 0 1-103.04 27.605333z m-1.194667 383.914667a53.333333 53.333333 0 1 1 102.997334-27.605333 53.333333 53.333333 0 0 1-102.997334 27.605333z m-149.205333-425.386667a53.333333 53.333333 0 1 1 103.04-27.605333 53.333333 53.333333 0 0 1-103.04 27.605333z"
            fill="#1989fa"
            p-id="2366"></path>
        </svg>
      </template>
    </van-nav-bar>

    <div class="record">
      <div class="recording-state" :style="state == 'recording' || state == 'uploading' ? 'display:flex' : 'display:none'">
        <div class="icon"></div>
        <div v-if="state == 'recording'">录制</div>
        <div v-if="state == 'uploading'">录制结束</div>
        <div class="time">{{ formatSeconds(time) }}</div>
        <div class="size">{{ formatBytes(size) }}</div>
      </div>

      <video class="video" ref="recordRef" muted autoplay playsinline></video>

      <div class="material" :style="`color:${color}`">
        {{ material ? material.content : '' }}
        <div class="double-arrow"></div>
      </div>
    </div>

    <div class="footer">
      <div class="button" :class="state" @click="changeState">
        <template v-if="state == 'recording'">
          <van-icon name="stop-circle" />
          结束录制
        </template>
        <template v-else-if="state == 'uploading'">
          <van-loading :size="20" color="#fff">视频上传中({{ percent }})，请稍后 </van-loading>
        </template>
        <template v-else>
          <van-icon name="play-circle" />
          开始录制
        </template>
      </div>
    </div>

    <van-popup v-model:show="popupColorVisible" closeable close-icon="close" position="bottom" :overlay="false" :lock-scroll="false" :style="{ height: '30%' }">
      <div style="height: 40px; padding: 20px 10px; font-weight: 500">设置文字颜色</div>
      <div class="colors">
        <div class="color" :style="`background:${item}`" v-for="item in colors" @click="selectColor(item)">
          <van-icon class="color-checked" v-if="item == color" name="success" />
        </div>
      </div>
    </van-popup>
  </div>
</template>

<style lang="scss" scoped>
.page {
  height: 100vh;
  display: flex;
  flex-direction: column;
  .record {
    position: relative;
    flex: 1;
    .video {
      position: absolute;
      width: 100%;
      height: 100%;
      background: #000;
    }
  }

  .footer {
    display: flex;

    .button {
      flex: 1;
      flex-shrink: 0;
      padding: 12px 0;
      background: #165dff;
      color: #fff;
      text-align: center;
    }

    .button:not(:last-child) {
      border-right: 1px solid #fff;
    }

    .button.recording {
      background: red;
    }
  }

  .recording-state {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 100;
    color: #fff;
    align-items: center;
    font-family: '微软雅黑';
    font-size: 12px;
  }

  .recording-state .icon {
    background: red;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    margin-right: 4px;
  }

  .recording-state .time,
  .recording-state .size {
    margin-left: 5px;
  }

  .material {
    font-family: 'Roboto', sans-serif, Arial;
    font-size: 14px;
    white-space: pre-wrap;
    word-break: break-word;
    position: absolute;
    top: 20px;
    width: 100%;
    left: 0;
    height: 50%;
    overflow: auto;
    padding: 10px;
    z-index: 10;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }

  .transform-center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  .colors {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px 10px;
    padding: 10px;

    .color {
      height: 10vw;
      border-radius: 3px;
      box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
      display: flex;
      align-items: center;
      justify-content: center;

      .color-checked {
        font-size: 18px;
      }
    }
  }

  .navbar {
    background: #fff !important;
    // background: #165DFF !important;
    text-align: center;

    .van-icon {
      color: #1989fa !important;
      // color:#fff !important;
    }

    .van-nav-bar__title {
      color: #000 !important;
      // color:#fff !important;
      font-size: 14px;
      margin-left: 52px;
      max-width: 80%;
    }
  }
}
</style>
